/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package im.clusterhead;

import im.eventpackage.Event;
import im.filters.ContentEventFilter;
import im.general.AbstractListenBehaviour;
import im.general.Config;
import im.messages.BaseMessage;
import im.messages.NotifyCHMessage;
import im.messages.NotifyRecipientMessage;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author brownstone
 */
public class NotifyListenBehaviour extends AbstractListenBehaviour {

    ClusterHeadAgent ch;

    public NotifyListenBehaviour(ClusterHeadAgent ch) {
        this.ch = ch;
        //mt = MessageTemplate.MatchPerformative(BaseMessage.NOTIFY);
        //mt = MessageTemplate.MatchEncoding("Notify");
        mt = MessageTemplate.MatchEncoding(Config.NOTIFY_NAME);
    }

    @Override
    protected void handleMessage(ACLMessage msg) {
        NotifyCHMessage notifyCHMessage = null;
        Event e = null;
        try {
            notifyCHMessage = (NotifyCHMessage) msg.getContentObject();
        } catch (UnreadableException ex) {
            Logger.getLogger(NotifyListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }

        ContentEventFilter contentFilter = new ContentEventFilter();

        //ACLMessage nmsg = new ACLMessage(msg.getPerformative());
        //nmsg.setEncoding(Config.NOTIFY_NAME);

        NotifyCHMessage nchmsg=null;
        try {
            nchmsg = (NotifyCHMessage) msg.getContentObject();
        } catch (UnreadableException ex) {
            Logger.getLogger(NotifyListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }


        ACLMessage nmsg = new ACLMessage(ACLMessage.SUBSCRIBE);
        nmsg.setEncoding(Config.NOTIFY_NAME);

        try {
            nmsg.setContentObject((Serializable) nchmsg.getEvent());
        } catch (IOException ex) {
            Logger.getLogger(NotifyListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }

        Vector filtered = new Vector();
        Vector recipients = (Vector) ch.getNodesList().clone();
        recipients.retainAll(notifyCHMessage.getRecipients());
        if(recipients.size()==0)
            return;
        
        ContentEventFilter contentEventFilter = new ContentEventFilter();

        Iterator i = recipients.iterator();
        while(i.hasNext()) {
            String recipient = (String) i.next();
            if(contentEventFilter.filterSubscription(nchmsg.getEvent(),ch.getNodeInfo(recipient).getContentSubscription()))
                ch.addReceiver(recipient, nmsg);
            else
                filtered.add(recipient);
        }

        ch.sendMessage(nmsg);

        NotifyRecipients(Config.EVENT_SERVICE_NAME, nchmsg.getEvent(), filtered);
    }

    public void NotifyRecipients(String coordinator, Event e, Vector recipients) {
//TODO ricevere la lista dei recipients all'eventservice
        ACLMessage nmsg = new ACLMessage(ACLMessage.UNKNOWN);



        try {
            nmsg.setContentObject(new NotifyRecipientMessage(recipients, e));
        } catch (IOException ex) {
            Logger.getLogger(NotifyListenBehaviour.class.getName()).log(Level.SEVERE, null, ex);
        }
        ch.addReceiver(coordinator, nmsg);
        nmsg.setEncoding(Config.NOTIFY_RECIPIENTS);
        nmsg.setPerformative(ACLMessage.SUBSCRIBE);
        ch.sendMessage(nmsg);

    }
}


